package cn.zzuisa.deutsch.controller;

import cn.zzuisa.deutsch.base.Constant;
import cn.zzuisa.deutsch.base.R;
import cn.zzuisa.deutsch.entity.DictIndex;
import cn.zzuisa.deutsch.entity.LogsOperation;
import cn.zzuisa.deutsch.entity.Member;
import cn.zzuisa.deutsch.log.annotation.BussinessLog;
import cn.zzuisa.deutsch.mapper.LogsOperationMapper;
import cn.zzuisa.deutsch.service.LogService;
import cn.zzuisa.deutsch.service.MemberService;
import cn.zzuisa.deutsch.utils.IpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.Data;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.helper.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.*;

import org.apache.http.Header;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

@RestController
@RequestMapping("/dic")
public class godicController {

    @Autowired
    MemberService memberService;
    @Autowired
    LogService logService;
    private static final String YOUDAO_URL = "http://openapi.youdao.com/api";

    private static final String APP_KEY = "4d4f8615507b7be1";

    private static final String APP_SECRET = "Xym1fWU74iodNanJkdSP52pXd1anyLHa";


    public static void main(String[] args) throws IOException {

    }

    public static String requestForHttp(String url, Map<String, String> params) throws IOException {

        /** 创建HttpClient */
        CloseableHttpClient httpClient = HttpClients.createDefault();

        /** httpPost */
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> paramsList = new ArrayList<NameValuePair>();
        Iterator<Map.Entry<String, String>> it = params.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> en = it.next();
            String key = en.getKey();
            String value = en.getValue();
            paramsList.add(new BasicNameValuePair(key, value));
        }
        httpPost.setEntity(new UrlEncodedFormEntity(paramsList, "UTF-8"));
        CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
        try {
            Header[] contentType = httpResponse.getHeaders("Content-Type");
            org.apache.http.HttpEntity httpEntity = httpResponse.getEntity();
            String json = EntityUtils.toString(httpEntity, "UTF-8");
            EntityUtils.consume(httpEntity);
            return json;
        } finally {
            try {
                if (httpResponse != null) {
                    httpResponse.close();
                }
            } catch (IOException e) {
            }
        }
    }


    /**
     * 生成加密字段
     */
    public static String getDigest(String string) {
        if (string == null) {
            return null;
        }
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        byte[] btInput = string.getBytes();
        try {
            MessageDigest mdInst = MessageDigest.getInstance("SHA-256");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (byte byte0 : md) {
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }

    /**
     * @param result 音频字节流
     * @param file   存储路径
     */
    private static void byte2File(byte[] result, String file) {
        File audioFile = new File(file);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(audioFile);
            fos.write(result);

        } catch (Exception e) {
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public static String truncate(String q) {
        if (q == null) {
            return null;
        }
        int len = q.length();
        String result;
        return len <= 20 ? q : (q.substring(0, 10) + len + q.substring(len - 10, len));
    }

    public String getDict(String word) throws IOException {
        String url = "http://www.godic.net/Home/TranslationAjax?to=zh-CN&from=de&text=" + word + "&contentType=text%2Fplain";
        Connection con = Jsoup.connect(url);
        Document doc = con.post();
        return word + "<br>" + URLEncoder.encode(doc.text(), "UTF-8");
    }


    @GetMapping("/trans")
    public String trans(String content) throws IOException {
        content = URLDecoder.decode(content, "UTF-8");
        System.out.println("接受:" + content);
        Map<String, String> params = new HashMap<String, String>();

        String url = "http://www.godic.net/Home/TranslationAjax";
        Connection con = Jsoup.connect(url);
        Map<String, String> form = new HashMap<>();
        form.put("to", "de");
        form.put("from", "zh-CN");
        form.put("text", content.replaceAll("\\+", "%20"));
        form.put("contentType", "text/plain");
        con.data(form);
        Document doc = con.post();
        System.out.println("doc1:" + doc.text());
        if (eq(doc.text(), content) >= doc.text().split(" ").length / 2) {
            Connection con2 = Jsoup.connect(url);
            String tmp = form.get("to");
            form.put("from", "de");
            form.put("to", "zh-CN");
            System.out.println(form.get("to") + form.get("text"));
            con2.data(form);
            doc = con2.post();
            System.out.println("doc2:" + doc.text());
//            String q = form.get("text");
//            String salt = String.valueOf(System.currentTimeMillis());
//            params.put("from", "zh-CHS");
//            params.put("to", "de");
//            params.put("signType", "v3");
//            String curtime = String.valueOf(System.currentTimeMillis() / 1000);
//            params.put("curtime", curtime);
//            String signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET;
//            String sign = getDigest(signStr);
//            params.put("appKey", APP_KEY);
//            params.put("q", q);
//            params.put("salt", salt);
//            params.put("sign", sign);
//            /** 处理结果 */
//            requestForHttp(YOUDAO_URL, params);


            return content + "<!--&--><br>" + doc.text();
        }
        System.out.println("trans:" + content + "<!--&--><br>" + doc.text());
        return content + "<!--&--><br>" + doc.text();
    }

    public int eq(String str1, String str2) {
        String[] s1 = str1.split(" ");
        String[] s2 = str2.split(" ");
        int count = 0;
        for (String t : s1) {
            for (String t2 : s2) {
                if (t2.equals(t)) {
                    ++count;
                    break;
                }
            }
        }
        return count;
    }

    @Data
    static class Dict {
        String core;
        String exemplify;
        String ver;
    }

    @GetMapping
    public R leave(@RequestParam String word, HttpServletRequest request) {
        try {
            HttpSession session = request.getSession();
            Member member = (Member) session.getAttribute("member");
            member.setExperience(member.getExperience() + 20);
            if (member.getLevel() != member.getExperience())
                member.setLevel(member.getExperience() / 100 + 1);
            memberService.updateById(member);
            String ip = IpUtil.getClientIp(request);
            LogsOperation logs = new LogsOperation();
            logs.setContent("【留言】：" + word);
            logs.setRoleId(-1l);
            logs.setUserName(member.getName());
            logs.setUserId(member.getId());
            logs.setIp(ip);
            logs.setType("互动");
            logs.setCreateTime(LocalDateTime.now());
            logService.save(logs);
        } catch (Exception e) {
            System.out.println("未登录");
            return R.error("留言失败，原因：检测不到登录状态");
        }
        return R.success("留言成功！");
    }

    @GetMapping("/hot")
    public R<DictIndex> getHot(String cityName) {
        RestTemplate restTemplate = new RestTemplate();
        String uri = "http://www.godic.net/home/HomePageList";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> entity = new HttpEntity<String>(headers);
        String strbody = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class).getBody();
        DictIndex dictIndex = JSONObject.parseObject(strbody, DictIndex.class);
        return R.success(dictIndex);
    }

    @Data
    static class Video {
        String videoSrc;
        String content;
    }


    @BussinessLog(value = "观看热门德语听力：#")
    @GetMapping("video")
    public R<Video> getVideo(@RequestParam String url, @RequestParam String title, @RequestParam(required = false) String share, HttpServletRequest request) throws IOException {
        System.out.println("hey:" + url);

        try {
            HttpSession session = request.getSession();
            Member member = (Member) session.getAttribute("member");
            member.setExperience(member.getExperience() + 2).setLevel(member.getExperience() / 100 + 1);
            memberService.updateById(member);

        } catch (Exception e) {
            System.out.println("未登录");
        }
        RestTemplate restTemplate = new RestTemplate();
        Document doc = Jsoup.connect(url)
                .timeout(Constant.TIMEOUT).get();
        String videoSrc = doc.select(".video").attr("src");
        doc.select(".videoArea").remove();
        Elements content = doc.select(".article .contents");
        Video video = new Video();
        video.setVideoSrc(videoSrc);
        video.setContent(content.text());
        return R.success(video);
    }

    @BussinessLog(value = "查词/翻译：#")
    @GetMapping("getv/{word}")
    public R<Dict> getVerb(@PathVariable String word, HttpServletRequest request) throws IOException {
        try {
            HttpSession session = request.getSession();
            Member member = (Member) session.getAttribute("member");
            member.setExperience(member.getExperience() + 1).setLevel(member.getExperience() / 100 + 1);
            memberService.updateById(member);

        } catch (Exception e) {
            System.out.println("未登录");
        }
        Dict dict = new Dict();
        word = URLEncoder.encode(word, "UTF-8");//
        String url = "http://www.godic.net/dicts/de/" + word.replaceAll("\\+", "%20");
//                .replaceAll("%C3%B6", "ö")
//                .replaceAll("%C3%A4", "ä")
//                .replaceAll("%C3%BC", "ü");
        System.out.println("word：" + word);
        Document doc = null;
        try {
            doc = Jsoup.connect(url)
                    .timeout(Constant.TIMEOUT).get();

        } catch (Exception e) {
            dict.setCore(trans(word));
            return R.success(dict);
        }
        Elements script = doc.getElementsByTag("script");
        script.remove();
        Elements content = doc.select("#ExpFCChild");
        System.out.println("content:" + content.html());
        String img = "";
        if (!StringUtil.isBlank(doc.select("#page-status").val())) bk:{
            String vers = "http://www.godic.net/Dicts/de/tab-detail/expcg";
            Document verdoc = null;
            Connection con = Jsoup.connect(vers);
            Map<String, String> form = new HashMap<>();
            String status = doc.select("#page-status").val();
            System.out.println("status:" + status);
            form.put("status", status);
            con.data(form);
            try {
                verdoc = con.post();
            } catch (Exception e) {
                break bk;
            }
            verdoc.getElementsByTag("script").remove();
            verdoc.select("#cg-speak").remove();
            verdoc.select("#sp-cg-category").remove();
            verdoc.select("#sp-cg-category-selector").remove();
            verdoc.select("ul").remove();
            System.out.println(verdoc.html());
            dict.setVer(verdoc.html());
            img = doc.select("#ExpFCChild img").get(0).toString() + "<br>";
        }
        content.select("a").remove();
        content.select("input").remove();
        content.select("img").remove();
        Elements exemplifies = doc.select("#lj_div .lj_item");
        String title = StringUtil.isBlank(doc.select(".word").html()) ? "" : doc.select(".word").html() + "<br>";
        String sub = doc.select(".phonitic-line span").html();
        List<Map<String, Object>> list = new ArrayList<>();
        dict.setCore(img + title + sub + content.html());
        System.out.println("@@@@@@@@@@@@@@@@@@@@:"+content.html());
        if (StringUtil.isBlank(content.html())) {
            String subcore = doc.select("#tabs-nuwiki").html();
            if(StringUtil.isBlank(subcore)){
                String core = URLDecoder.decode(getDict(word), "UTF-8");
//            dict.setCore(core);
//            System.out.println("core:" + core);
//            if ((int) core.charAt(0) > 252) { // 德语中ü ascII =252
                dict.setCore(trans(word));
                //            }
            }
            else {
                dict.setCore(subcore);
            }

        }
        dict.setExemplify(exemplifies.html());
        if (StringUtil.isBlank(dict.getExemplify())) {
            exemplifies = doc.select("#ExpLJChild .lj_item");
            dict.setExemplify(exemplifies.html());
        }
        return R.success(dict);
    }
}
